package com.spring.ioc.demo.dao;

import com.spring.ioc.demo.domain.User;

import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class UserDaoImpl implements UserDao{

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void init(){
        System.out.println(UserDaoImpl.class.getName()+"初始方法被调用了");
    }

    @Override
    public List<User> queryUsers(Map<String, Object> param){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            connection = dataSource.getConnection();
            String sql ="select * from user where name = ?";
            // 获取预处理 statement
            preparedStatement = connection.prepareStatement(sql);

            // 设置参数，第一个参数为sql 语句中参数的序号（从1开始），第二个参数为设置的值
            preparedStatement.setObject(1,param.get("name"));

            // 向数据库发送sql,获取结果集
            rs = preparedStatement.executeQuery();

            // 遍历结果集
            List<User> results = new ArrayList<>(1);
            User result = null;
            Class<?> clazz = User.class;
            while (rs.next()){
                  // 遍历一行数据便创建一个对象
                  result = (User) clazz.newInstance();
                  // 获取结果集的元数据
                  ResultSetMetaData metaData = rs.getMetaData();
                  // 获取每一行的数据总数
                  int columnCount = metaData.getColumnCount();
                  // 遍历每一行
                  for(int i = 0;i<columnCount;i++){
                      // 获取每一列的名称
                      String cloumName = metaData.getColumnName(i+1);
                      // 通过反射获取指定的属性名称（列名必须和属性名一致）
                      Field field = clazz.getDeclaredField(cloumName);
                      // 设置暴力破解
                      field.setAccessible(true);
                      // 给私有属性赋值
                      field.set(result,rs.getObject(i+1));
                  }
                results.add(result);
            }
            return results;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(preparedStatement != null){
                try {
                    preparedStatement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return null;
    }
}
